package com.luo.bbs.front.webapi.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.bbs.front.service.IQuestionService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.luo.bbs.front.webapi.mapper.CollectMapper;
import com.luo.bbs.front.webapi.mapper.QuestionMapper;
import com.luo.bbs.front.webapi.mapper.TagMapper;
import com.luo.bbs.front.webapi.pojo.UserLoginPrincipal;
import com.luo.bbs.front.webapi.rabbitmq.RabbitMQConfig;
import com.luo.common.exception.BBSServiceException;
import com.luo.common.restful.JsonPage;
import com.luo.common.restful.ResponseCode;

import com.luo.pojo.Collect;
import com.luo.pojo.question.dto.QuestionDTO;
import com.luo.pojo.question.entity.Question;
import com.luo.pojo.question.vo.QuestionVO;
import com.luo.pojo.tag.entity.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.BooleanUtils;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author bin.cn
 * @since 2023-01-19
 */
@DubboService
@Service
@Slf4j
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements IQuestionService {

    @Autowired
    private QuestionMapper questionMapper;
    @Autowired
    private TagMapper tagMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private CollectMapper collectMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public QuestionVO post(QuestionDTO questionDTO) {
        Question question = new Question();
        log.debug("接受的参数是{}", questionDTO);
        BeanUtils.copyProperties(questionDTO, question);

        if (getUserId() == null || getUserNickName() == null) {
            throw new BBSServiceException(ResponseCode.UNAUTHORIZED, "用户未登录");
        }

        question.setUserId(getUserId());
        question.setNickname(getUserNickName());
        question.setStatus(0);
        log.debug("帖子参数整理完毕");
        int row = questionMapper.insert(question);
        if (row != 1) {
            throw new BBSServiceException(ResponseCode.INTERNAL_SERVER_ERROR, "系统繁忙请稍后重试！");
        }
        QuestionVO questionVO = new QuestionVO();
        BeanUtils.copyProperties(question, questionVO);
        return questionVO;
    }

    //查询某个版块下的帖子列表,通过审核的,未被删除的
    @Override
    public List<QuestionVO> getByTag(String title,Integer userId) {
        QueryWrapper<Tag> queryTag = new QueryWrapper<>();
        queryTag.eq("name", title);
        Tag tag = tagMapper.selectOne(queryTag);
        if (tag == null) {
            throw new BBSServiceException(ResponseCode.NOT_FOUND, "不存在该标签！");
        }
        Integer tagId = tag.getId();

        QueryWrapper<Question> queryQuestion = new QueryWrapper<>();
        queryQuestion.eq("tag_Id", tagId);
        queryQuestion.eq("status", 1);//审核
        queryQuestion.eq("delete_status",0);
        queryQuestion.orderByDesc("gmt_create");//发布时间排序
        List<Question> questionList = questionMapper.selectList(queryQuestion);
        //如果该版块下没有列表直接返回，省去赋值
        if (questionList.isEmpty()) {
            return null;
        }
        List<QuestionVO> list = new ArrayList<>();
        for (Question question : questionList) {
            QuestionVO questionVO = new QuestionVO();
            BeanUtils.copyProperties(question, questionVO);
            isCollect(questionVO,userId);
            list.add(questionVO);
        }
        return list;
    }

    //为是否收藏属性赋值
    private void isCollect(QuestionVO questionVO,Integer userId) {
        String key = COLLECT_KEY + questionVO.getId();
        Boolean member = stringRedisTemplate.opsForSet().isMember(key, userId.toString());
        questionVO.setIsCollect(BooleanUtils.isTrue(member));
    }

    //通过ID查询帖子详情
    @Override
    public QuestionVO getById(Integer id,Integer userId) {
        Question question = questionMapper.selectById(id);
        if (question == null) {
            throw new BBSServiceException(ResponseCode.NOT_FOUND, "不存在该帖子！");
        }
        QuestionVO questionVO = new QuestionVO();
        BeanUtils.copyProperties(question, questionVO);
        String avatar = questionMapper.getAvatar(question.getUserId(), question.getId());
        questionVO.setAvatar(avatar);
        isCollect(questionVO,userId);
        return questionVO;
    }

    //查询用户发帖数
    @Override
    public Integer countByUser(Integer userId) {
        //判断用户是否存在，略
        //判断用户传过来的ID是否是当前用户
        log.debug("接收的参数是{}", userId);
        if (!userId.equals(getUserId())) {
            throw new BBSServiceException(ResponseCode.FORBIDDEN, "用户身份异常！");
        }
        //查询该用户有多少帖子
        Integer count = questionMapper.selectCount(
                new QueryWrapper<Question>().eq("user_id", userId)
        );
        return count;
    }

    //分页查询所有帖子,通过审核的
    @Override
    public JsonPage<QuestionVO> getAll(Integer pageNum, Integer pageSize) {
        QueryWrapper<Question> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 1).eq("delete_status",0)
                .orderByDesc("gmt_create");
        PageHelper.startPage(pageNum, pageSize);
        List<Question> questions = questionMapper.selectList(queryWrapper);
        List<QuestionVO> answer = new ArrayList<>();
        for (Question question : questions) {
            QuestionVO questionVO = new QuestionVO();
            BeanUtils.copyProperties(question, questionVO);
            answer.add(questionVO);
        }
        return JsonPage.restPage(new PageInfo<>(answer));
    }


    String COLLECT_KEY = "question:collect:";
    //收藏or取消收藏
    @Override
    public int collect(Integer questionId) {
        Question question = questionMapper.selectById(questionId);
        if (question == null) {
            throw new BBSServiceException(ResponseCode.NOT_FOUND, "该帖子不存在！");
        }
        Integer userId = getUserId();
        String key = COLLECT_KEY + questionId;
        Boolean member = stringRedisTemplate.opsForSet().isMember(key, userId.toString());
        if (BooleanUtils.isFalse(member)){
            //未收藏过
            boolean update = update().setSql("collect_views=collect_views+1").eq("id", questionId).update();
            //收藏表插入数据,
            Collect collect =new Collect();
            collect.setQuestionId(questionId);
            collect.setUserId(userId);
            collect.setGmtCreate(LocalDateTime.now());
            //通过消息队列发送，避免一直数据库交互
            rabbitTemplate.convertAndSend(RabbitMQConfig.COLLECT_EX,RabbitMQConfig.COLLECT_ROUT1,collect);
            System.out.println("消息发送完成");

            if (update){
                stringRedisTemplate.opsForSet().add(key,userId.toString());
                return 601;//收藏则返回601
            }else {
                throw new BBSServiceException(ResponseCode.INTERNAL_SERVER_ERROR,"系统繁忙");
            }
        }
        //收藏过，取消收藏
        boolean isSuccess = update().setSql("collect_views=collect_views-1").eq("id", questionId).update();
        if (isSuccess){
            stringRedisTemplate.opsForSet().remove(key,userId.toString());
            Collect collect =new Collect();
            collect.setQuestionId(questionId);
            collect.setUserId(userId);
            rabbitTemplate.convertAndSend(RabbitMQConfig.COLLECT_EX,RabbitMQConfig.COLLECT_ROUT2,collect);
            return 602; //取消收藏
        }else {
            throw new BBSServiceException(ResponseCode.INTERNAL_SERVER_ERROR,"系统繁忙");
        }

    }

    @Override
    public  List<QuestionVO> getMy(Integer userId) {
        QueryWrapper<Question> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",userId);
        List<Question> questions = questionMapper.selectList(queryWrapper);
        List<QuestionVO> list = new ArrayList<>();
        for (Question question : questions) {
            QuestionVO questionVO = new QuestionVO();
            BeanUtils.copyProperties(question,questionVO);
            list.add(questionVO);
        }
        return list;
    }


    public UserLoginPrincipal getUserInfo() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserLoginPrincipal principal = (UserLoginPrincipal) authentication.getPrincipal();
        if (principal == null) {
            throw new BBSServiceException(ResponseCode.UNAUTHORIZED, "未登录！");
        }
        return principal;
    }

    public Integer getUserId() {
        if (getUserInfo() == null) {
            return null;
        }
        return getUserInfo().getId();
    }

    public String getUserNickName() {
        if (getUserInfo() == null) {
            return null;
        }
        return getUserInfo().getNickname();
    }
}
